﻿using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq.Expressions;

namespace System.Reactive.Linq
{
	public static partial class Qbservable
	{
		public static IQbservable<IList<TSource>> Zip<TSource>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Ensures(Contract.Result<IQbservable<IList<TSource>>>() != null, null, "Contract.Result<IQbservable<IList<TSource>>>() != null");
			return null;
		}

		public static IQbservable<IList<TSource>> Zip<TSource>(this IQbservableProvider provider, params IObservable<TSource>[] sources)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Ensures(Contract.Result<IQbservable<IList<TSource>>>() != null, null, "Contract.Result<IQbservable<IList<TSource>>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<TSource, TResult>(this IQbservableProvider provider, IEnumerable<IObservable<TSource>> sources, Expression<Func<IList<TSource>, TResult>> resultSelector)
		{
			Contract.Requires(provider != null, null, "provider != null");
			Contract.Requires(sources != null, null, "sources != null");
			//Contract.Requires(Contract.ForAll(sources, observable => observable != null), null, "Contract.ForAll(sources, observable => observable != null)");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<TFirst, TSecond, TResult>(this IQbservable<TFirst> first, IEnumerable<TSecond> second, Expression<Func<TFirst, TSecond, TResult>> resultSelector)
		{
			Contract.Requires(first != null, null, "first != null");
			Contract.Requires(second != null, null, "second != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<TFirst, TSecond, TResult>(this IQbservable<TFirst> first, IObservable<TSecond> second, Expression<Func<TFirst, TSecond, TResult>> resultSelector)
		{
			Contract.Requires(first != null, null, "first != null");
			Contract.Requires(second != null, null, "second != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, Expression<Func<T1, T2, T3, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, Expression<Func<T1, T2, T3, T4, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

#if !WINDOWS_PHONE
		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, Expression<Func<T1, T2, T3, T4, T5, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, Expression<Func<T1, T2, T3, T4, T5, T6, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, Expression<Func<T1, T2, T3, T4, T5, T6, T7, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(source11 != null, null, "source11 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(source11 != null, null, "source11 != null");
			Contract.Requires(source12 != null, null, "source12 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(source11 != null, null, "source11 != null");
			Contract.Requires(source12 != null, null, "source12 != null");
			Contract.Requires(source13 != null, null, "source13 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(source11 != null, null, "source11 != null");
			Contract.Requires(source12 != null, null, "source12 != null");
			Contract.Requires(source13 != null, null, "source13 != null");
			Contract.Requires(source14 != null, null, "source14 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(source11 != null, null, "source11 != null");
			Contract.Requires(source12 != null, null, "source12 != null");
			Contract.Requires(source13 != null, null, "source13 != null");
			Contract.Requires(source14 != null, null, "source14 != null");
			Contract.Requires(source15 != null, null, "source15 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}

		public static IQbservable<TResult> Zip<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>(this IQbservable<T1> source1, IObservable<T2> source2, IObservable<T3> source3, IObservable<T4> source4, IObservable<T5> source5, IObservable<T6> source6, IObservable<T7> source7, IObservable<T8> source8, IObservable<T9> source9, IObservable<T10> source10, IObservable<T11> source11, IObservable<T12> source12, IObservable<T13> source13, IObservable<T14> source14, IObservable<T15> source15, IObservable<T16> source16, Expression<Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, TResult>> resultSelector)
		{
			Contract.Requires(source1 != null, null, "source1 != null");
			Contract.Requires(source2 != null, null, "source2 != null");
			Contract.Requires(source3 != null, null, "source3 != null");
			Contract.Requires(source4 != null, null, "source4 != null");
			Contract.Requires(source5 != null, null, "source5 != null");
			Contract.Requires(source6 != null, null, "source6 != null");
			Contract.Requires(source7 != null, null, "source7 != null");
			Contract.Requires(source8 != null, null, "source8 != null");
			Contract.Requires(source9 != null, null, "source9 != null");
			Contract.Requires(source10 != null, null, "source10 != null");
			Contract.Requires(source11 != null, null, "source11 != null");
			Contract.Requires(source12 != null, null, "source12 != null");
			Contract.Requires(source13 != null, null, "source13 != null");
			Contract.Requires(source14 != null, null, "source14 != null");
			Contract.Requires(source15 != null, null, "source15 != null");
			Contract.Requires(source16 != null, null, "source16 != null");
			Contract.Requires(resultSelector != null, null, "resultSelector != null");
			Contract.Ensures(Contract.Result<IQbservable<TResult>>() != null, null, "Contract.Result<IQbservable<TResult>>() != null");
			return null;
		}
#endif
	}
}